package com.twu.biblioteca;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class BibliotecaApp {

    private PrintStream printStream;
    private LibraryManager manager;
    private UserInputCondition condition;


    public BibliotecaApp(PrintStream printStream, LibraryManager manager,  UserInputCondition condition){
        this.printStream = printStream;
        this.manager = manager;
        this.condition = condition;
    }

    public static void main(String[] args) {
        ArrayList<Book> bookList = populateBooksList();
        PrintStream printStream = System.out;
        UserInputCondition conidtion = new UserInputCondition();
        LibraryManager manager = new LibraryManager(bookList, printStream);

        new BibliotecaApp(printStream, manager, conidtion).runApp();
    }

    private static ArrayList<Book> populateBooksList() {
        ArrayList<Book> tempBookList = new ArrayList<Book>();
        tempBookList.add(new Book("Gulliver's Travels"));
        tempBookList.add(new Book("The Hobbit"));
        tempBookList.add(new Book("Call of the Wild"));

        return tempBookList;
    }

    private void runApp() {
        welcomeMessage();
        listAvailableBooks();
        displayListOptions();
        handleUserListChoice(new BufferedReader(new InputStreamReader(System.in)));
    }

    public void welcomeMessage() {
        printStream.println("Welcome to Biblioteca!");
        printStream.println();
    }

    public void listAvailableBooks() {
        manager.printBooks();
    }

    public void displayListOptions() {
        printStream.println("Enter Number for Option.");
        printStream.println("Enter 1 to list books");
        printStream.println("Enter 2 to checkout book");
        printStream.println("Enter 3 to return book");
        printStream.println("Enter 4 to exit Biblioteca");
    }


    public void handleUserListChoice(BufferedReader reader) {
        String input;

        while (condition.keepGoing()) {
            input = getUserInput(reader);
            processUserInput(input, reader);
        }
    }

    private String getUserInput(BufferedReader reader) {
        String input = "0";

        try {
            input = reader.readLine();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return input;
    }

    private void processUserInput(String input, final BufferedReader reader) {
        Map<String, CommandMenu> menuMap = new HashMap<String, CommandMenu>();

        menuMap.put("1", new CommandMenu() {
           public void go(){listAvailableBooks();}
        });

        menuMap.put("2", new CommandMenu() {
            public void go() {
                checkOutBook(reader);
            }
        });

        menuMap.put("3", new CommandMenu() {
            public void go() {
               returnBook(reader);
            }
        });

        menuMap.put("4", new CommandMenu() {
            public void go() {
                condition.makeFalse();
            }
        });



        if (menuMap.containsKey(input)) {
            menuMap.get(input).go();
        } else {
             printStream.println("Select a valid option!");
        }
    }

    private String getNameFromUser(BufferedReader reader) {
        printStream.println("Enter your name: ");
        return getUserInput(reader);
    }

    private String getTitleFromUser(BufferedReader reader) {
        printStream.println("Enter a title:");
        return getUserInput(reader);
    }

    private  void returnBook(BufferedReader reader){
        String title = getTitleFromUser(reader);
        manager.returnBook(title);
    }

    private void checkOutBook(BufferedReader reader){
        String title = getTitleFromUser(reader);
        String name = getNameFromUser(reader);
        manager.checkOutBook(title, name);
    }
}